package com.yunkeji.framework.config;

import cn.hutool.core.thread.BlockPolicy;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.concurrent.Executor;

/**
 * 线程池
 *
 * @author 老张
 */
@Configuration
public class PoolConfig {

    /**
     * 控制id总数的分页，例如50W，ids，内存最多存在LinkedBlockingDeque 容量*5000,当线程池第一波5W消费完毕，第二波5万才会存在在内存中继续被该线程池消费
     *
     * @return
     */
    @Bean("httpExecutor")
    public Executor pushMsgExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        // 核心池大小
        taskExecutor.setCorePoolSize(30);
        // 最大线程数
        taskExecutor.setMaxPoolSize(100);
        // 队列程度
        taskExecutor.setQueueCapacity(Integer.MAX_VALUE);
        // 线程空闲时间
        taskExecutor.setKeepAliveSeconds(30);
        // 线程前缀名称
        taskExecutor.setThreadNamePrefix("httpExecutor--");
        // 该方法用来设置 线程池关闭 的时候 等待 所有任务都完成后，再继续 销毁 其他的 Bean，
        // 这样这些 异步任务 的 销毁 就会先于 数据库连接池对象 的销毁。
        taskExecutor.setWaitForTasksToCompleteOnShutdown(true);
        // 任务的等待时间 如果超过这个时间还没有销毁就 强制销毁，以确保应用最后能够被关闭，而不是阻塞住。
        taskExecutor.setAwaitTerminationSeconds(30);
        // 线程不够用时由调用的线程处理该任务
        taskExecutor.setRejectedExecutionHandler(new BlockPolicy());
        return taskExecutor;
    }
}
